using AutoMapper;
using MediatR;
using RBAC.Domain.MaterialManage;
using RBAC.ErrorCode;
using RBAC.Interstructrue.Base;
using RBAC.Write.Api.Application.Command.ERP.MaterialFile;
using System.Transactions;

namespace RBAC.Write.Api.Application.Handler.ERP.MaterialFile
{
    /// <summary>
    /// 创建物料基本档案处理类
    /// </summary>
    public class CreateMaterialHandler : IRequestHandler<CreateMaterialCommand, APIResult<long>>
    {
        private readonly IBaseRepository<Mater> materRepository;
        private readonly IBaseRepository<MaterType> materTypeRepository;
        private readonly ILogger<CreateMaterialHandler> logger;
        private readonly IMapper mapper;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="materRepository">物料仓储接口</param>
        /// <param name="materTypeRepository">物料类型仓储接口</param>
        /// <param name="logger">日志接口</param>
        /// <param name="mapper">对象映射接口</param>
        public CreateMaterialHandler(
            IBaseRepository<Mater> materRepository,
            IBaseRepository<MaterType> materTypeRepository,
            ILogger<CreateMaterialHandler> logger,
            IMapper mapper)
        {
            this.materRepository = materRepository;
            this.materTypeRepository = materTypeRepository;
            this.logger = logger;
            this.mapper = mapper;
        }

        /// <summary>
        /// 处理创建物料基本档案请求
        /// </summary>
        /// <param name="request">创建物料命令</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>创建结果</returns>
        public async Task<APIResult<long>> Handle(CreateMaterialCommand request, CancellationToken cancellationToken)
        {
            APIResult<long> result = new APIResult<long>();

            try
            {
                logger.LogInformation("开始创建物料基本档案: {MaterName}", request.MaterName);

                // 1. 数据验证
                if (string.IsNullOrWhiteSpace(request.MaterCode))
                {
                    result.Code = APIEnums.Error;
                    result.Msg = "物料编码不能为空";
                    logger.LogWarning("物料编码验证失败");
                    return result;
                }

                if (string.IsNullOrWhiteSpace(request.MaterName))
                {
                    result.Code = APIEnums.Error;
                    result.Msg = "物料名称不能为空";
                    logger.LogWarning("物料名称验证失败");
                    return result;
                }

                // 2. 检查物料编码是否已存在
                var existingByCode = materRepository.QueryFirstOrDefault<int>(
                    "SELECT COUNT(1) FROM Mater WHERE MaterCode = @MaterCode AND IsDeleted = false",
                    new { MaterCode = request.MaterCode });

                if (existingByCode > 0)
                {
                    result.Code = APIEnums.Error;
                    result.Msg = "物料编码已存在";
                    logger.LogWarning("物料编码已存在: {MaterCode}", request.MaterCode);
                    return result;
                }

                // 3. 检查物料名称是否已存在
                var existingByName = materRepository.QueryFirstOrDefault<int>(
                    "SELECT COUNT(1) FROM Mater WHERE MaterName = @MaterName AND IsDeleted = false",
                    new { MaterName = request.MaterName });

                if (existingByName > 0)
                {
                    result.Code = APIEnums.Error;
                    result.Msg = "物料名称已存在";
                    logger.LogWarning("物料名称已存在: {MaterName}", request.MaterName);
                    return result;
                }

                // 4. 验证物料分类是否存在（如果提供了分类ID）
                if (request.MaterTypeId.HasValue && request.MaterTypeId.Value > 0)
                {
                    var typeExists = materTypeRepository.QueryFirstOrDefault<int>(
                        "SELECT COUNT(1) FROM MaterType WHERE Id = @Id AND IsDeleted = false",
                        new { Id = request.MaterTypeId.Value });

                    if (typeExists == 0)
                    {
                        result.Code = APIEnums.Error;
                        result.Msg = "指定的物料分类不存在";
                        logger.LogWarning("物料分类验证失败: {MaterTypeId}", request.MaterTypeId.Value);
                        return result;
                    }
                }

                // 5. 创建物料实体
                var mater = mapper.Map<Mater>(request);
                mater.CreateTime = DateTime.Now;
                mater.IsDeleted = false;
                mater.CreateUser = "admin"; // 默认管理员用户
                mater.Status = request.Status;

                logger.LogInformation("物料基本档案映射完成: MaterName={MaterName}, MaterTypeId={MaterTypeId}",
                    mater.MaterName, mater.MaterTypeId);

                using (TransactionScope tran = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
                {
                    try
                    {
                        // 6. 保存物料基本档案信息
                        var sql = @"INSERT INTO Mater (MaterCode, MaterName, Unit, SupplyMode, ModelSpec, DrawingNo, SpecDesc, Status, MaterTypeId, CreateTime, IsDeleted, CreateUser) 
                                   VALUES (@MaterCode, @MaterName, @Unit, @SupplyMode, @ModelSpec, @DrawingNo, @SpecDesc, @Status, @MaterTypeId, @CreateTime, @IsDeleted, @CreateUser);
                                   SELECT LAST_INSERT_ID();";

                        var parameters = new
                        {
                            mater.MaterCode,
                            mater.MaterName,
                            mater.Unit,
                            mater.SupplyMode,
                            mater.ModelSpec,
                            mater.DrawingNo,
                            mater.SpecDesc,
                            mater.Status,
                            mater.MaterTypeId,
                            mater.CreateTime,
                            mater.IsDeleted,
                            mater.CreateUser
                        };

                        var materId = materRepository.QueryFirstOrDefault<long>(sql, parameters);

                        if (materId <= 0)
                        {
                            throw new InvalidOperationException("物料基本档案创建失败，返回的ID无效");
                        }

                        tran.Complete();

                        result.Code = APIEnums.Success;
                        result.Data = materId;
                        result.Msg = "物料基本档案创建成功";

                        logger.LogInformation("物料基本档案 {MaterName} 创建完成，ID: {MaterId}",
                            request.MaterName, materId);
                    }
                    catch (Exception ex)
                    {
                        logger.LogError(ex, "创建物料基本档案过程中发生错误: {Message}", ex.Message);
                        result.Code = APIEnums.Error;
                        result.Msg = "创建物料基本档案失败";
                        result.Data = 0;
                        throw;
                    }
                }
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "创建物料基本档案失败: {Message}", ex.Message);
                result.Code = APIEnums.Error;
                result.Msg = "创建物料基本档案失败";
                result.Data = 0;
            }

            return result;
        }
    }
}